package com.woniu.common;

import com.auth0.jwt.interfaces.DecodedJWT;
import com.fasterxml.jackson.databind.ObjectMapper;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;

import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

@Component
public class JwtInterceptor implements HandlerInterceptor {

    @Autowired
    private JwtUtil jwtUtil;

    @Override
    public boolean preHandle(HttpServletRequest request,
                             HttpServletResponse response,
                             Object handler) throws Exception {

        // 如果不是控制器方法，直接放行
        if (!(handler instanceof HandlerMethod)) {
            return true;
        }

        HandlerMethod handlerMethod = (HandlerMethod) handler;

        // 检查是否需要认证
        boolean requireAuth = handlerMethod.hasMethodAnnotation(AuthAccess.RequireAuth.class);
        boolean optionalAuth = handlerMethod.hasMethodAnnotation(AuthAccess.OptionalAuth.class);

        if (!requireAuth && !optionalAuth) {
            return true; // 不需要认证的方法
        }

        // 获取token
        String authHeader = request.getHeader("Authorization");
        if (authHeader == null || !authHeader.startsWith("Bearer ")) {
            if (requireAuth) {
                sendErrorResponse(response, 401, "缺少认证token");
                return false;
            }
            return true; // 可选认证，没有token也放行
        }

        String token = authHeader.substring(7);

        try {
            // 验证token
            DecodedJWT jwt = jwtUtil.verifyToken(token);

            // 将用户信息存入请求属性
            Integer userId = jwt.getClaim("userId").asInt();
            String username = jwt.getClaim("username").asString();

            request.setAttribute("userId", userId);
            request.setAttribute("username", username);
            request.setAttribute("jwt", jwt);

        } catch (Exception e) {
            if (requireAuth) {
                sendErrorResponse(response, 401, "Token无效或已过期");
                return false;
            }
            // 可选认证，token无效也放行（但不设置用户信息）
        }

        return true;
    }

    private void sendErrorResponse(HttpServletResponse response, int code, String message)
            throws IOException {
        response.setStatus(code);
        response.setContentType("application/json;charset=UTF-8");

        Map<String, Object> error = new HashMap<>();
        error.put("code", code);
        error.put("msg", message);
        error.put("data", null);

        response.getWriter().write(new ObjectMapper().writeValueAsString(error));
    }
}